/*
===========================================================================
This source file is part of DyLab (Dynamic Laboratory)
For the latest info, see http://dylab.googlecode.com

Copyright (c) 2006-2008 Lukas Krejci
(krejci.lukas@volny.cz)

This file is part of DyLab.

    DyLab is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    DyLab is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DyLab.  If not, see <http://www.gnu.org/licenses/>.
===========================================================================
*/

#ifndef __dylab_ComHaptics_h__
#define __dylab_ComHaptics_h__

//===========================================================================================
#include <dylab/simulation/ISimulationComponent.h>
#include <dylab/utils/components/ComponentBase.h>
#include <dylab/simulation/EventDispatcher.h>

//===========================================================================================
namespace dylab {
   
    /** Simulation haptics component type.
	@remarks
		This class defines an interface for the simulation haptics component type.
		Components of this type are responsible for implementing the requested haptics driver.
     @warning 
		Never use pointers to the declared interfaces without 
		locking up the whole ComHaptics::Instace object!
    */
    class DYLAB_EXPORT ComHaptics 
        : public ISimulationComponent
        , public ComponentBase<ComHaptics>
    {
    public:
		/// The name that acts as an alias of the default haptic device.
        static const String DEFAULT_DEVICE_NAME;

    public:
        class DYLAB_EXPORT EventDispatcher
            : public dylab::EventDispatcher<HapticsEvent>
        {
        };
        //-----------------------------------------------------------------------------

    public:
		/** This class defines the interface of one haptic device.
		*/
        class DYLAB_EXPORT IDevice
        {
        public:
            /** Returns the name given to this device at the time of its creation.
			@returns
				The name of this device.
             */
            virtual String getName() const = 0;

            /** Synchronizes data to/from the haptics system (and possibly sends some events).
             */
            virtual void update() = 0;

            /** Retrieves the current haptics position.
            @remarks 
				This value changes only after the update() method is called.
			@returns
				Current position of this haptic device.
            */
            virtual Vector3 getPosition() const = 0;

            /** Stores new force to be sent to the haptic device.
            @remarks 
				The force is sent to the haptic device only after the update() method is called.
			@param[in] _force
				The force vector that will be send to this haptic device.
            @note 
				The force is not cummulating when called multiple times.
            */
            virtual void setFroce(const Vector3 & _force) = 0;
        };
        //-----------------------------------------------------------------------------

    public:

        ComHaptics(const String & _componentName);
        virtual ~ComHaptics();

        /** Creates new haptic device and stores it under the supplied name.
		@param[in] _name
			The name assigned to the created haptic device.
		@returns
			The newly created haptic device.
        */
        virtual IDevice * createDevice(const String & _name = DEFAULT_DEVICE_NAME) = 0;

        /** Returns previously created haptic device stored under the supplied name.
		@param[in] _name
			The name assigned to the requested haptic device.
		@returns
			The requested haptic device.
        */
        virtual IDevice * getDevice(const String & _name = DEFAULT_DEVICE_NAME) = 0;

        /** Returns previously created haptic device stored under the supplied name.
		@param[in] _name
			The name assigned to the requested haptic device.
		@returns
			The requested haptic device.
        */
        virtual const IDevice * getDevice(const String & _name = DEFAULT_DEVICE_NAME) const = 0;

        /** Destroys previously created device stored under the supplied name.
		@param[in] _name
			The name assigned to the haptic device that should be destroyed.
        */
        virtual void destroyDevice(const String & _name = DEFAULT_DEVICE_NAME) = 0;

        /** Calls update method for all created haptic devices.
        */
        virtual void updateAllDevices() = 0;

        /** Destroys all created haptic devices.
        */
        virtual void destroyAllDevices() = 0;
    };
}
//===========================================================================================
#endif // __dylab_ComHaptics_h__
